/******************************************************************
 *
 *  !Exec v.2 - an ArmBob wimp program           GCW 30/11/94
 *
 *  Run command file with pathname of file dragged onto icon.
 *
 *  See doc.tutorial.4
 *
 ******************************************************************/
#include Bob:W_Events
#include Bob:W_Messages

#include Bob:wimp.templates
#include Bob:wimp.ev_process

main()
{
 @b = @(newstring(500));  // global message buffer

 /* Create vector of responses to the task manager */
 handler = newvector(20);         
 handler[Mouse_Click] = do_Mouse_Click;
 handler[Menu_Selection] = do_Menu_Selection;
 handler[User_Message] = handler[User_Message_Recorded] = do_Message;
 /* All but 4 of handler's components are nil */

 in (mesg_list= newstring(8)) put
     { Message_DataLoad; 0; }        // the messages we want to receive

 /* register task with window manager */
 wimp_init(310,"Exec",mesg_list);

 /* create vector of windows and get their handles */  
 (wind = newvector(1))[0] = "info";
 info = templates("<Exec$Dir>.Templates",wind)[0];

 icon = make_icon();
 menu = make_menu();

 /* global register vector for functions in loops that use swi */
 r = newvector(8);

 /******* the central loop takes place here ********/
 /* &1933 is the reason code mask.
    @b is the message buffer address.
    handler is the vector of message handlers.
    nil is the current value of the "user-parameter" - we
    might want to pass round a parameter to the handlers
    containing extra data that each could decode.  */

 (maskptr = newvector(1))[0] = &1933;
 event_process(maskptr,@b,handler,nil); 
}

do_Mouse_Click(a,user,m)
{
 if ((word(a+12)==-2) &&                   // iconbar
     (word(a+16)==icon))                   // icon
   switch (word(a+8))
    {
      case 2:                           // Menu button
       r[1] = menu;                     // use global r
       r[2] = word(a)-64;
       r[3] = 140;
       swi("Wimp_CreateMenu",r);
       break;
      case 1:                          // Adjust button
      case 4:                          // Select button
       oscli("Filer_run <Exec$Dir>.Exec");  // Exec must be a textfile
       break;
     }  
 return TRUE;  // i.e. continue
}

do_Menu_Selection(a,user,m)
{
 return (word(a)!=1);     
}

do_Message(a,user,m)
{
 switch(word(a+16))
    {
     case Message_Quit:
       return FALSE;  // i.e. do not continue
       break;
     case Message_DataLoad:  
        if (word(a+20)==-2 && word(a+24)==icon)
           act(a,user_process);
        return TRUE;
        break;
     default:
        return TRUE;
        break;
    }
}
 
make_icon()
{
 local r;
 in @b put 
 {
  -1;                       // right of icon bar
   0;                       // xmin of bounding box
   0;                       // ymin of bounding box
   64;                      // xmax of bounding box
   68;                      // ymax of bounding box
   &1700210a;               // icon flags
   @(sprite = "!exec");     // pointer to sprite name
   1;                       // Wimp sprite area
   8;                       // Length of spritename
 }
 (r = newvector(8))[1] = @b;
 swi("Wimp_CreateIcon",r);
 return(r[0]);
}

make_menu()
{
 in (menu = newstring(72)) put
 {
  "Exec"; 0; 0;                           // Menu title
   &70207;                                // colours
   100;                                   // width
   44;                                    // height 
   0;                                     // gap
   0;
   info;                                  // submenu
   1+(1<<4)+(9<<12)+(1<<16)+(7<<24);      // flags
   "Info"; 0; 0;                          // item title
   &80;                                   // last item
   -1;                                    // no submenu
   1+(1<<4)+(9<<12)+(1<<16)+(7<<24);      // flags
   "Quit"; 0;                             // item title
 }
 return(menu);
}

act(a,f)
{
 local filename, filetype;
 filename = $(a+44);
 filetype = word(a+40);
 putword(a+16,Message_DataLoadAck);
 putword(a+12,word(a+8));
 r[0] = User_Message_Acknowledge;
 r[1] = a;
 r[2] = 0;
 swi("Wimp_SendMessage",r);
 f(filename,filetype);
}

// ------- end of harness, do your own stuff here -------- //

user_process(fname,ftype)
{
 oscli("WimpTask Obey -c <Exec$Dir>.Exec "+fname); 
}
